/**
 *  @file SAXHandler.h
 */
#ifndef _SAXHANDLER_H_
#define _SAXHANDLER_H_

#include "../../common/BaseObject.h"
#include "../../text/CFString.h"
#include "../../collections/LinkedHashtableT.h"

namespace cppflib
{

namespace xml
{

namespace sax
{

/** 
 *  Handler for derived class to implement so as to receive notifications from a SAXParser
 *  when parsing an XML
 */
class _DLLAPI SAXHandler : public BaseObject
{
public:
    typedef enum
    {
       HERR_WARN = 0x01,
       HERR_ERROR = 0x02,
       HERR_FATAL = 0x04
    } xmlhandlererror_t;

private:
    int nestedLevel;  ///< root node is at level 0
    CFString currentFullTagName;   
    int handlerError;

protected:
    SAXHandler(void)
    {
       this->nestedLevel = -1;
       this->handlerError = 0;
    }

    int GetNestedLevel() { return nestedLevel; }
    const CFString & GetCurFullTagName() { return currentFullTagName; }
public:
    
    virtual ~SAXHandler(void)
    {
    }

    // these are called by parser
    void IncrementNestedLevel() { ++this->nestedLevel; }
    void DecrementNestedLevel() { --this->nestedLevel; }
    void SetCurFullTagName(const CFString &curFullTagName) { this->currentFullTagName = curFullTagName; }
    void ClearErrorWarning() { this->handlerError = 0; }
    void MarkErrorWarning(xmlhandlererror_t err) { this->handlerError |= static_cast<int>(err); }
    bool IsErrorMarked() { return ((this->handlerError & HERR_ERROR) != 0 || 
                                   (this->handlerError & HERR_FATAL) != 0); }

    // below should be overriden by derived class

    virtual void StartDocument() = 0;
    virtual void EndDocument() = 0;
    /**
     *  @param [in] nameSpace -- empty at this moment
     */
    virtual void StartElement(const CFString &nameSpace, const CFString &fullTagName, 
                              const collections::LinkedHashtableT<CFString, CFString> &attributes) = 0;
    virtual void ElementContent(const CFString &text) = 0;
    virtual void EndElement(const CFString &nameSpace, const CFString &fullTagName) = 0;
    virtual void Error(const CFString &msg) = 0;
    virtual void FatalError(const CFString &msg) = 0;
    virtual void Warning(const CFString &msg) = 0;

};

} // end of namespace sax

} // end of namespace xml

} // end of namespace cppflib


#endif
